package Day18.Inner02;

/**
 * @author HYHwtx
 * @version 1.0
 * @date 2022/2/25 15:48
 */


/**
 * 匿名内部类的演示
 *
 * 1.本质还是类
 * 2.内部类
 * 3.该类没有名字（又有名字）
 * 4.同时还是一个对象
 * 说明：匿名内部类是定义在外部类的局部位置，比如 方法中，并且没有类名
 *
 * 基本语法：new 类 或者 接口 (参数列表){
 *     类体
 * }
 */
public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04=new Outer04();
        outer04.method();
    }
}
class Outer04{//外部类
    private int n1=10;//属性
    public void method(){//方法
        //基于接口的匿名内部类
        //1.需求：想使用IA接口，并且创建对象
        //2.传统方式，写一个类，实现该接口，并且创建对象
        //3.需求是Tiger/Dog类只使用一次，后面不在使用
        //4.可以使用匿名内部类来简化开发
        //5.tiger的编译类型是什么？看左边IA的接口类型
        //6.tiger的运行类型是什么？就是匿名内部类 Outer04$1
        /*
        我们看底层，在底层会分配一个类名Outer04$1
        class XXX implements IA{
            public void cry(){
                 System.out.println("老虎叫唤...");
            }
        }
         */
        //7.jdk底层在创建匿名内部类Outer04$1，立马创建了Outer04$1实例，并且把地址返回给了tiger
        IA tiger =new IA(){
            public void cry(){
                System.out.println("老虎叫唤...");
            }
        };
        System.out.println("tiger的运行类型是="+tiger.getClass());//getClass()获取到当前对象的运行类型
        tiger.cry();
        IA dog=new IA() {
            @Override
            public void cry() {
                System.out.println("小狗叫唤...");
            }
        };
        dog.cry();

        //演示基于类的匿名内部类
        //分析
        //1.father的编译类型是谁？ Father
        //2.father的运行类型是谁？Outer04$2
        //3.底层会创建匿名内部类

        /*
        class Outer04$2 extends Father {
            类似于：
            @Override
            public void test() {
                System.out.println("匿名内部类重写了test方法");
            }
        }
         */
        //4.同时也直接返回了匿名捏不累的Outer04$2的对象
        //5.注意：ktm参数列表会传递给构造器
        Father father=new Father("ktm"){
            @Override
            public void test() {
                System.out.println("匿名内部类重写了test方法");
            }
        };
        System.out.println("Father对象的运行类型是="+father.getClass());
        father.test();
        father.test();
        father.test();

        //基于抽象类的匿名内部类
        Animal animal=new Animal() {
            @Override
            void eat() {
                System.out.println("小狗吃骨头");
            }
        };
        animal.eat();
    }
}

interface IA{//接口
    public void cry();
}

class Father{//类
    public Father(String name) {//构造器
        System.out.println("接收到的name="+name);
    }
    public void test(){//方法
    }
}
abstract class Animal{//抽象类
    abstract void eat();
}
